package com.zj.guava.eventbus.DirectoryAndFileWatch;

import com.google.common.eventbus.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.*;

public class DirectoryMonitor implements TargetMonitor {
    Logger logger = LoggerFactory.getLogger(DirectoryMonitor.class);
    private WatchService watchService;
    private Path path;
    private EventBus bus;
    private volatile boolean start = false;

    public DirectoryMonitor(EventBus bus, String targetPath) {
        this.bus = bus;
        this.path = Paths.get(targetPath);
        bus.register(new FileChangeListener());

    }

    @Override
    public void startMonitor() throws IOException {
        this.watchService = FileSystems.getDefault().newWatchService();
        this.path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
        this.start = true;
        while (start) {
            WatchKey watchKey = null;
            try {

                watchKey = watchService.take();
                watchKey.pollEvents().forEach(event -> {
                    WatchEvent.Kind<?> kind = event.kind();
                    Path path = (Path) event.context();
                    path.toFile().lastModified();
                    if (path.toString().endsWith("txt")) {
                        logger.info("event.context {}", path);

                        Path resolve = this.path.resolve(path);
                        bus.post(new FileChangeEvent(resolve, kind));
                    }

                });

            } catch (Exception e) {
                this.start = false;
            } finally {
                if (watchKey != null) {
                    watchKey.reset();
                }
            }
        }

    }

    @Override
    public void storMonitor() throws IOException {
        logger.info("stop monitor {}", path);
        Thread.currentThread().interrupt();
        this.start = false;
        this.watchService.close();

    }
}
